package com.example.seed.web;

import com.example.seed.config.security.TokenService;
import com.example.seed.dto.LoginSpecification;
import com.example.seed.entity.LoginUser;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

@RestController
@RequestMapping
public class LoginController {

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoginController.class);
    
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private TokenService tokenService;

    /**
     * 处理用户登录请求。
     *
     * @param login 包含登录账户和密码的请求体。
     * @return 返回一个包含访问令牌(access_token)、令牌类型(token_type)和过期时间(expires_in)的响应实体。
     */
    @PostMapping("/login")
    public ResponseEntity<Map<String, String>> login(@RequestBody LoginSpecification login) {
        // 创建基于用户名和密码的认证令牌
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(login.getAccount(), login.getPassword());

        // 记录登录尝试信息
        log.info("时间->{},文件->{},authenticationToken->{}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), this.getClass().getSimpleName(), authenticationToken);
        // 对用户进行认证
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        // 将认证结果设置到安全上下文中
        SecurityContextHolder.getContext().setAuthentication(authenticate);
        // 生成并获取登录成功后的用户令牌
        String token = tokenService.getToken((LoginUser) authenticate.getPrincipal());
        // 构建并返回包含令牌信息的响应实体
        return ResponseEntity.ok(Map.of("access_token", token, "token_type", "Bearer", "expires_in", "3600"));
    }


    /**
     * 注销
     *
     * @return {@link String}
     */
    @GetMapping("/logout")
    public ResponseEntity<Boolean> logout(HttpServletRequest request) {
        boolean success = tokenService.logout(request);
        return ResponseEntity.ok(success);
    }

    @Secured("ADMINISTRATOR")
    @GetMapping("test")
    @PreAuthorize("hasAuthority('role:add')")
    public String home() {
        return "home";
    }
}
